Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android gravity vector Godot 2.1 #8088

Merged
merged 1 commit into from
Mar 24, 2017

Conversation

BastiaanOlij
Copy link
Contributor

This PR adds support for reading the gravity vector sensor. This is a vector the OS calculates from the accelerometer sensor with some nice math to filter out any user vibration/movement. It is very useful in getting a more accurate "down" vector for stabilizing device orientation or for getting an approximate user movement by subtracting this vector from the accelerometer output.

Mainly it's added to create parity with the core motion changes we did for iOS for issue #7503

In theory the test project I did for coremotion should work to test this as well:
https://github.com/BastiaanOlij/TestCoreMotion

Due to lacking a suitable android device that actually has these sensors I've not been able to actually test this so I'm hoping someone with device that has all 3 sensors could give this a go?

And since @akien-mga refactored half the 2.1 branch this probably works in Godot 3 too.

@ghost
Copy link

ghost commented Mar 21, 2017

I don't know if it's me, and it's probably just on my end, but I was unable to build due to the following error when I executed ./gradlew build:

godot-2.1-build/platform/android/java/src/org/godotengine/godot/Godot.java:698: cannot find symbol
symbol : method gravity(float,float,float)
location: class org.godotengine.godot.GodotLib
GodotLib.gravity(x,y,z);

A shame because this looks great, very exciting. I hope someone else can test.

EDIT: Looks like you might have forgot some code/never built with Gradle (the shittiest build platform in the world but I digress) so the error might not have come up. I'll work on a fix.

@ghost
Copy link

ghost commented Mar 21, 2017

I had to patch the following in order to compile:

platform/android/java/src/org/godotengine/godot/GodotLib.java
platform/android/java_glue.h
platform/android/java_glue.cpp

Then when I ran TestCoreMotion on an Android device (which has an accelerometer and magnetometer but no gyroscope) the vertical orientation seemed flipped and no gravity information was retrieved (0.00, 0.00, 0.00). I was still able to (sort of) look around. I might see if I can fix this later. Who knows? But probably not.

testcoremotion-android
godot-2.1-patch.zip

@BastiaanOlij
Copy link
Contributor Author

Well that means there is still something missing in passing the gravity vector through, or it simply isn't supported. I didn't change anything in the gyro code so the missing gyro data suggest that you either do not have a gyro or that I managed to break something :)

Without a gyro the OS possibly lacks the data to extract the gravity vector from the accelerometer, but if you're sure you have a gyro then I wonder what went wrong..

Also the orientation code is really based on having a gyro and stabilizing it. The code you have in your project which combines the accelerometer and magnetometer using a cross product is much better suited. I'm either going to need to build a check in that if there is no gyro data it takes that path, or find a good way to combine the two approaches :)

I really need to get my hands on a proper android phone, doing these changes blind is not doing anyone alot of favours :) Thanks for trying it out, I'll have a closer look at your changes, I had completely missed java_glue :).

@BastiaanOlij
Copy link
Contributor Author

@fluffrabbit I think I've added all your changes, they looked sound. I don't know why I didn't get errors while compiling or maybe it won't show up till you actually try to add it to the device?

@akien-mga Also changed some spaces to tab ;)

@BastiaanOlij
Copy link
Contributor Author

@fluffrabbit I'm mixing up projects, it was Jasons code that I was looking at, he had a really nice bit of code for combining accelerometer and magnetometer data:) so many different people working on solving this puzzle, pretty cool really :)

@ghost
Copy link

ghost commented Mar 21, 2017

Without a gyro the OS possibly lacks the data to extract the gravity vector from the accelerometer, but if you're sure you have a gyro then I wonder what went wrong..

Android is supposed to know what planet you are on and calculate a gravity vector in m/s^2. How it would know what planet one is on is questionable (I guess it assumes Earth or something, kind of geocentric if you ask me but w/e) but supposedly that factors in somehow.

you either do not have a gyro or that I managed to break something
accelerometer and magnetometer but no gyroscope

The code you have in your project which combines the accelerometer and magnetometer using a cross product is much better suited. I'm either going to need to build a check in that if there is no gyro data it takes that path, or find a good way to combine the two approaches :)

I think your code is better because stability is inherently better when factoring in gravity, with or without a gyroscope. When you move the phone to look around, the accelerometer vector momentarily gets skewed because it is measuring, what else, acceleration. So in my code the view sort of "swings" exaggeratedly. The actual math involved to derive a stabilized gravity vector is a mystery to me, and maybe it does depend on the gyroscope, but unfortunately the material is really dense and heady so I don't know.

I had completely missed java_glue

It helps to use Github's search feature in the Godot codebase. I just searched for all instances of things like "accelerometer" and "gyroscope".

As for purchasing an Android device with a gyroscope, you'd be looking at paying quite a bit. Walgreens has $25 starter phones which should cover all your needs.

it was Jasons code that I was looking at, he had a really nice bit of code for combining accelerometer and magnetometer data

I'd love to see it.

@BastiaanOlij
Copy link
Contributor Author

@fluffrabbit btw, looking at your screenshot, the accelerometer data seems out of scale or at least not normalised (it will be normalised in code) and down seems to be pointed to positive Z, instead of negative Y as it would be on iOS. Confusing:)

@ghost
Copy link

ghost commented Mar 21, 2017

@BastiaanOlij Accelerometer on Android is measured in meters per second ^ 2, hence 9.8. If normalized is normal, then crunchitize me cap'n

@BastiaanOlij
Copy link
Contributor Author

@fluffrabbit , no idea what is normal, I only have my iPhone to go on. It doesn't really matter what the scale is as long as you know what it is :)

I'm more concerned about the orientation, friend of mine who has an Android phone with a Gyro has already let me know the axis are reversed on the gyro data.

Now with the iOS implementation I took care to align all the axis with the axis inside of Godot because I needed to adjust them anyway with Apple changing the orientation to compensate for your screen orientation, while it looks like on Android we get the figures as they are...

@ghost
Copy link

ghost commented Mar 21, 2017

on Android we get the figures as they are

That was the information I wanted to know. There is code in Godot which changes the orientation of the accelerometer on Android based on the orientation of the screen. I also copied and pasted that code to get_magnetometer when I implemented that on Android. Oh boy, here lurk strange bugs.

@BastiaanOlij
Copy link
Contributor Author

@fluffrabbit , I'll have a closer look at the code when I'm home tonight. I might be wrong, I couldn't find code that did anything too strange but I've only started looking at the android code a day or so ago so I'm not as familiar with it yet.

@ghost
Copy link

ghost commented Mar 22, 2017

I couldn't find code that did anything too strange

Somebody might or might not have done a rewrite in the past few months, I can't clearly remember. But it must still re-orient the screen on the accelerometer side, not sure about magnetometer. I'd swear there was some code to do that at the time that I implemented get_magnetometer on Android.

@ghost
Copy link

ghost commented Mar 23, 2017

I don't know what has changed. Gremlins in the code. But now I am getting a gravity vector on Android with TestCoreMotion. Holding the phone in landscape orientation straight out in front of me, the gravity vector is about 0.4, -9.5, 0.2. Resting flat on the floor, it is about 0.1, 0.2, 9.9. Magnetometer works correctly. Accelerometer seems to be inverted on both axis.

Question is, which is more correct -- get_accelerometer on Android, or get_accelerometer on iOS?

No gyroscope is present in the phone so the gravity vector must come from somewhere else.

Useracc stays at a constant 0, 0, 0 as there is no gyro here. Something might be able to be fudged but it's not coming down the pipe from the Android API.

@akien-mga akien-mga merged commit 492f6e0 into godotengine:2.1 Mar 24, 2017
@BastiaanOlij BastiaanOlij deleted the android_gravity_2.1 branch March 24, 2017 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants